package be.kdg.bombermanunlimited.server.network;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.rmi.AccessException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

import be.kdg.bombermanunlimited.client.CentralRegistry;
import be.kdg.bombermanunlimited.client.CentralRegistry.BombermanObjects;
import be.kdg.bombermanunlimited.server.audiomanager.AudioManager;
import be.kdg.bombermanunlimited.server.remote.finalclasses.Game;
import be.kdg.bombermanunlimited.server.rmi.ClientSocketFactory;
import be.kdg.bombermanunlimited.server.rmi.ServerSocketFactory;

public class NetworkManagerTest {
	private static int port = 2020;

	private NetworkManagerTest() {
		String ip = getLocalIpAddress();
		System.setProperty("java.rmi.server.hostname", ip);
		CentralRegistry.getRegistry().putObject(BombermanObjects.LOCAL_IP, ip);
		System.out.println("Local ip set to: "
				+ System.getProperty("java.rmi.server.hostname"));

		try {
			new SettingsServer(port + 1);
			Game game = new Game();
			NetworkManager nm = new NetworkManager(game,
					new ClientSocketFactory(), new ServerSocketFactory());
			AudioManager am = new AudioManager();
			nm.addNetworkManagerListener(am);
			LocateRegistry.createRegistry(port);
			LocateRegistry.getRegistry(port).rebind("/NetworkManager", nm);
			LocateRegistry.getRegistry(port).rebind("/AudioManager", am);

			LocateRegistry.getRegistry(port).rebind("/Game", game);
			new Thread(new GameThread(game)).start();

		} catch (AccessException e) {
			e.printStackTrace();
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new NetworkManagerTest();
	}

	private String getLocalIpAddress() {
		try {
			Enumeration<NetworkInterface> tmp = NetworkInterface
					.getNetworkInterfaces();
			List<NetworkInterface> interfaces = Collections.list(tmp);
			List<String> possibleAddresses = new ArrayList<String>();

			for (int i = 0; i < interfaces.size(); i++) {
				NetworkInterface ni = interfaces.get(i);
				if (ni.isUp()) {
					String ip = "";
					List<InterfaceAddress> addresses = ni
							.getInterfaceAddresses();

					for (int j = 0; j < addresses.size(); j++) {
						if (addresses.get(j).getAddress().getHostAddress()
								.indexOf(":") == -1) {
							ip = addresses.get(j).getAddress().getHostAddress();
						}
					}

					if (!ip.equals("")) {
						possibleAddresses.add(ip);
						System.out.println(possibleAddresses.size() + ") "
								+ ni.getDisplayName() + ": " + ip);
					}
				}
			}

			System.out.print("Select interface: ");
			int index = -1;
			try {
				String in = new BufferedReader(new InputStreamReader(System.in))
						.readLine();
				index = Integer.parseInt(in);
			} catch (IOException e) {
				e.printStackTrace();
			}

			return (index > 0 && index <= possibleAddresses.size() ? possibleAddresses
					.get(index - 1) : "");
		} catch (SocketException e) {
			e.printStackTrace();
		}

		return "";
	}

	private class GameThread implements Runnable {
		private Game game;

		public GameThread(Game game) {
			this.game = game;
		}

		@Override
		public void run() {
			int previous = 0;

			try {
				while (!game.isFull()) {
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
					}

					if (game.getPlayerCount() != previous) {
						previous = game.getPlayerCount();
						System.out.println(previous + " joined");
					}
				}

				game.start();
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}

	}
}
